Zarządzanie pamięcią wirtualną w Windows NT
W systemie Windows NT każdy z procesów widzi przestrzeń adresową 4 GB pamięci.
Z tego dolne 2 GB mogą być wykorzystywane przez proces użytkownika, a górne
2 GB są zarezerwowane dla jądra systemu (są takie same dla każdego procesu).
W obszarze dolnym również mogą się znajdować obszary zarezerwowane przez system,
np. biblioteki DLL załadowane przez dany proces.

Począwszy od NT 4.0 Enterprise Edition zostało wprowadzone rozszerzenie pamięci
użytkownika do 3 GB, ze względu na wymagania aplikacji. W takim modelu
jądro ma do dyspozycji jedynie 1 GB górnej przestrzeni adresowej.
Podobnie jak w Linuksie,
w przestrzeni 4 GB pamięci mogą się znajdować obszary odpowiadające fizycznej
pamięci, pamięci w postaci plików wymiany, mogą być również obszary wolne.
Możliwe jest też odwzorowanie adresów wirtualnych
do innych plików, np. plików z kodem programu czy plików z danymi. Każdy obszar
pamięci fizycznej lub dyskowej może być przyporządkowany różnym procesom pod
dowolnymi adresami wirtualnymi.

Konkretny sposób adresowania pozostawia się
najczęściej procesorowi (tak jest dla i386 i Alphy) w przypadku stron poprawnych
i zależy tylko od systemu dla stron niepoprawnych. Ponieważ obecne procesory
udostępniają zazwyczaj kilka mechanizmów adresowania, wybór konkretnej
implementacji spośród dostępnych należy do systemu. Windows NT nie stosuje
żadnej segmentacji, w szczególności rejestry segmentowe procesora rodziny i386
są zawsze ustawione tak, aby wskazywały na początkowe 4 GB pamięci fizycznej.
Pamięć wirtualna jest podzielona na ramki o wielkości zależnej od platformy sprzętowej.
Na i386 jest to 4 KB, dla procesorów DEC Alpha jest to 8 KB.
Podobnie jak to ma miejsce w systemie Linux, adres wirtualny w WinNT jest podzielony,
ale składa się z trzech części. Adres katalogu stron jest przechowywany w rejestrze
procesora (inny dla każdego procesu). Pierwsze bity adresu wirtualnego to
pozycja w katalogu stron pola PTE (Page Table
Entry). Ten z kolei wskazuje na adres tabeli stron. Kolejne bity adresu
wirtualnego to pozycja w tejże tabeli, zawierającej PTE wskazujące na konkretną
ramkę. Ostatnie bity adresu to offset w ramce.
W podstawowym modelu maksymalna wielkość pamięci fizycznej to 4 GB. Są jednak
rozszerzenia w systemach Windows 2000 i późniejszych, które pozwalają pokonać to ograniczenie. Na procesorach Alpha
naturalne jest adresowanie 32 GB pamięci, ze względu na rozmiar ramki wynoszący
8 KB. Na platformach i386 technika Physical Address Extension (PAE) wykorzystuje
mechanizmy obecne w procesorach Pentium Pro i późniejszych do
zaadresowania 64 GB pamięci. Rozszerzenie adresu wirtualnego z 32 do 36 bitów
realizowane jest przy pomocy Address Windowing Extension (AWE API).

Pole PTE zawiera adres fizyczny ramki. Na procesorze i386 spośród 32 bitów
użyte jest na to tylko 20, pozostałe bity
są wykorzystane do informacji o stanie strony. Pięć z 12 bitów używa się do
oznaczenia zabezpieczenia strony przed niepowołanym dostępem, cztery do
oznaczenia pliku wymiany, w którym znajduje się strona
(a więc jest maksymalnie 16 plików wymiany), a trzy do oznaczenia
jej stanu (czy strona jest w pamięci czy na dysku i jaki jest jej aktualny
status). Ten standardowy podział może się jednak zmieniać, w zależności od
typu strony. Przykłady znaczenia poszczególnych bitów:
- Valid
- - bit poprawności strony,
- Accessed
- - ustawiany w momencie odwołania do strony, co pozwala
na wykrycie mało używanych stron,
- Dirty
- - strona była modyfikowana i powinna być zapisana,
- Writeable
- - czy strona jest do zapisu czy readonly,
- User access
- - czy strona może być modyfikowana przez użytkownika,
- Copy on write
- - strona powinna być skopiowana przed zapisem,
- Prototype
- - PTE, wskazujące na prototypowe PTE używane w pamięci dzielonej,
- Transition
- - strona jest w trakcie przechodzenia w stan nieaktywny.
Jeżeli strona znajduje się w pliku wymiany, 20-bitowy adres wskazuje na jej
pozycję w pliku. Jeżeli strona jest zamapowanym plikiem, np. fragmentem pliku
wykonywalnego, lub dużego pliku z danymi, 28 bitów jest indeksem w tablicy
systemowej zawierającej nazwę i ścieżkę pliku oraz pozycję.
W przypadku, gdy strona, do której następuje odwołanie, nie znajduje się w
pamięci fizycznej, następuje błąd braku strony. W skrajnym przypadku może to
spowodować odczyt trzech stron z dysku (strony zawierającej katalog, tablicę
stron i samej strony). Aby uniknąć takich przypadków, stosuje się algorytm
pola roboczego (working set) i rejestry podręczne TLB (Table Lookaside Buffers).
Będą one opisane w dalszej części.
Jeżeli występuje konieczność wczytania strony do pamięci, automatycznie jest
wczytywane także kilka sąsiadujących stron, bo jest duże prawdopodobieństwo, że
one również będą potrzebne.
Istnieją obszary pamięci, które nie podlegają
stronicowaniu, zwane nonpaged pools. Nie mogą one być zrzucone do pliku wymiany.
W takim obszarze znajduje się kod menedżera pamięci wirtualnej. Nie można
umieścić w takim obszarze żadnej z części programu użytkownika. Jest jednak
możliwe tzw. przypinanie stron, które pozwala na umieszczenie danej strony
na stałe w pamięci komputera (służy do tego funkcja VirtualLock). Nie
zaleca się przypinania stron, ponieważ zazwyczaj powoduje to więcej szkody niż
pożytku (zajmuje ona miejsce w polu roboczym, o czym czytaj niżej).
Każdy proces ma początkowo przydzieloną pewną ilość stron, które będą na pewno
przebywać w pamięci fizycznej. Jest to pole robocze procesu. Dokładniej jest
zadana minimalna i maksymalna wielkość pola roboczego. Jeżeli aktualnie
jego wielkość nie jest równa minimalnej, podlega ono przycinaniu (trimming).
Proces zarządzający pamięcią
wirtualną w celu optymalizacji okresowo zmniejsza ilość stron w polu roboczym
procesu. Jeżeli nie generuje to zbyt dużej ilości błędów braku strony, pole
robocze jest zmniejszane na stałe, a nadmiarowe strony trafiają do zbioru stron
ogólnego użytku dla wszystkich procesów.
Zmniejszanie pola roboczego przebiega
w dwóch fazach. Na początku strona nie jest usuwana z pamięci, a jedynie
oznaczana jako niepoprawna w polu PTE. Odwołanie do takiej strony generuje
jedynie programowy błąd braku strony, a nie stwarza konieczności odczytania
jej z dysku. Następnie strona jest oznaczana jako Modified lub Standby
zależnie od tego, czy została zmodyfikowana czy nie, przez co może być zrzucona na dysk
przez menedżera pamięci.
Proces może sam określać rozmiar pola roboczego, jeśli ma do tego uprawnienia
(służy do tego funkcja SetProcessWorkingSetSize). W pewnych przypadkach
możliwe jest całkowite wywłaszczenie procesu ze stron w pamięci, jeżeli
jest on przez długi czas nieaktywny, na przykład jeśli jest aktywny tylko
przy logowaniu. Jeżeli proces wróci do aktywności, musi być odczytane z pliku
wymiany całe jego pole robocze.
W systemie Windows NT rozróżnia się obszary pamięci zarezerwowanej
(reserved) i zatwierdzonej (commited). Wątek, który chce uzyskać obszar pamięci,
musi na początku zarezerwować pewną strefę adresową. Może być ona duża, nawet
większa od dostępnej pamięci fizycznej, ponieważ nie następuje jeszcze
przydzielenie pamięci. Następnie wątek zatwierdza wybrane części lub całą
strefę pamięci, którą zarezerwował. W tym momencie system przyporządkowuje
adresom pamięć fizyczną lub część pliku wymiany. Dzięki temu mechanizmowi
wątek ma pewność, że żaden inny wątek w tym samym procesie nie będzie korzystał
z zarezerwowanej przestrzeni adresowej.

Ponieważ adres komórki pamięci może być dowolny dla każdego z procesów,
konieczne jest zastosowanie pewnej techniki pamięci dzielonej.
Służą do tego prototypowe PTE. Pola PTE
poszczególnych procesów, opowiadające stronie pamięci dzielonej
wskazują nie na ramkę pamięci danych, ale na prototypowy PTE, który z kolei
wskazuje na docelowy blok pamięci dzielonej.
W całym systemie 8 MB przestrzeni adresowej przeznaczone jest
na prototypowe PTE.
Są one tworzone dopiero wtedy, gdy są potrzebne, więc nie jest tracona na nie
pamięć fizyczna.
Niektóre obszary pamięci dzielonej, np. kod programu mogą być tylko w
nietypowych przypadkach zmieniane w jednym z procesów współdzielących
pamięć. Weźmy pod uwagę dwa procesy równolegle wykonujące ten sam kod. Nie ma powodu,
aby przydzielać im dwa oddzielne obszary pamięci fizycznej na kod programu,
więc tworzy się
obszar pamięci dzielonej. Kiedy jednak stawiamy pułapkę w debuggerze dla
jednego z tych procesów, zachodzi potrzeba skopiowania fragmentu kodu dla
jednego z procesów. Stosuje się tutaj optymalizację copy-on-write.

System Windows NT
prowadzi bazę danych stron. Jest ona używana przez proces zarządzający
pamięcią wirtualną do
przydzielania i zwalniania stron pamięci. Wszystkie strony dzielą się na
siedem kategorii. Strony jednej kategorii są połączone w listę.

- Valid
- - strona jest w użyciu przez przynajmniej jeden proces,
- Modified
- - strona była aktywna, ale została zmieniona i nie jest jeszcze
zapisana na dysk,
- Modified No Write
- - strona była aktywna i została zmieniona, ale
nie będzie w najbliższym czasie zapisana na dysk,
- Standby
- - strona nie jest już w polu roboczym procesu, i nie została
zmieniona. Strony takie utrzymuje się w celu zmniejszenia ilości odczytów z
dysku w przypadku błędów braku strony,
- Free
- - strona nie jest już w użyciu, nie ma przydzielonego PTE. Może być
ona wykorzystana przez dowolny proces po wyzerowaniu,
- Zeroed
- - strona została wyzerowana i może być zaalokowana przez proces użytkownika.
- Bad
- - napotkano na błąd sprzętowy, strona nie będzie używana.
Kod wykonywalny procesu zarządzającego znajduje się w pliku NTOSKRNL.EXE.
Dzieli się on na sześć wątków o różnym priorytecie. Najważniejszy z nich to
Balance Set Manager. Zajmuje się on dobieraniem wielkości pól roboczych,
uruchamia inne wątki w razie potrzeby, np. wątku zerującego zwolnione strony
w celu ponownego użycia. Wybiera strony, które mają być wyrzucone z pamięci,
przybliżając algorytm LRU za pomocą bitów dostępu do strony.
Aby właściwie zarządzać pamięcią, oprócz tablic wskaźników PTE i bazy danych
stron konieczne jest posiadanie pewnej informacji o tym, co dane ramki
faktycznie reprezentują. Za każdym razem, kiedy tworzony jest obszar pamięci
dla procesu i przydzielane są ramki pamięci wirtualnej, konstruuje się strukturę
opisującą, co znajduje się w tych ramkach, na przykład kod programu,
biblioteki DLL czy blok danych używany przez konkretny proces. Struktura ta
nazywa się Virtual Address Descriptor (VAD). Każdy proces może mieć wiele
takich struktur. Są one połączone w rodzaj drzewa binarnego (drzewo
typu splay), dzięki czemu łatwy jest dostęp do ostatnio używanych VAD-ów,
i szybkie jest wyszukiwanie.
System udostępnia uprawnionemu procesowi funkcję VirtualQuery, która
podaje strukturę danych opisującą kolejne bloki pamięci wirtualnej.
Zawiera ona adres, rozmiar i prawa dostępu do bloku pamięci, stan
(zarezerwowany, zatwierdzony, wolny).
Jeżeli blok jest zatwierdzony lub zarezerwowany, to zawiera ona
informacje o tym, jaki był adres i prawa dostępu do bloku pamięci
w momencie rezerwowania (zobacz punkt 6). Jeden blok zarezerwowany może się
rozpaść na wiele bloków zarezerwowanych, zatwierdzonych, i wolnych na skutek
zatwierdzania i zwalniania pamięci wewnątrz bloku.
Zarządzanie pamięcią wirtualną w systemie Windows NT
This document was generated using the
LaTeX2HTML translator Version 2002 (1.62)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -html_version 3.2,latin2,unicode -split 0 -nosubdir -nonavigation ntvm.tex
The translation was initiated by Michal Matuszewski
Michal Matuszewski
|